<?php

// +----------------------------------------------------------------------
// | 版权所有 2017-2027 云南环拓科技有限公司，并保留所有权利。
// +----------------------------------------------------------------------
// | Copyright (c) 2017-2027 http://www.yn123.com All rights reserved.
// +----------------------------------------------------------------------
// | Notice: This code is not open source, it is strictly prohibited
// |         to distribute the copy, otherwise it will pursue its
// |         legal responsibility.
// | 注意：  这不是一个自由软件！您只能在不用于商业目的的前提下对程序代码进行修改和使用,
// |        不允许对程序代码以任何形式任何目的的再发布。
// +----------------------------------------------------------------------
// | Author: feraner <feraner@163.com> 
// | Date: 2020/1/3
// +----------------------------------------------------------------------

namespace app\common\services\statistics;

use app\common\facade\Arr;
use library\tools\Data;
use think\Db;

/**
 * 公共模块分析
 * Class BehaviorHandleService
 * @package app\common\services\statistics
 * @author feraner<feraner@163.com>
 * @date 2020/1/3
 */
class BehaviorHandleService extends BasicHandleService
{

    public function __construct()
    {
        parent::__construct();
    }


    /**
     * 公共分析入口
     * @param $handleData
     *
     * @return mixed|void
     * @throws \think\Exception
     * @throws \think\exception\PDOException
     */
    public function handle($handleData)
    {
        if ($this->isHandle($handleData)) {
            //是否需要增加UV
            $this->addUv = $this->addUvNum(
                Arr::get($handleData, 'userId'),
                Arr::get($handleData, 'logId')
            );

            $dayData = [
                'type'          => 1,
                'click_num'     => Db::raw('click_num + 1'),
                'start_time'    => $this->todayStart,
                'end_time'      => $this->todayEnd
            ];
            if ($this->addUv) {
                $dayData['uv'] = Db::raw('uv + 1');
            }
            if ($this->isApi) {
                $dayData['api_num'] = Db::raw('api_num + 1');
            }
            if ($this->__isPublishJob(Arr::get($handleData, 'urlArr'))) {
                $dayData['publish_num'] = Db::raw('publish_num + 1');
                $dayData['publish_job'] = Db::raw('publish_job + 1');
            }
            if ($this->__isPublishMarket(Arr::get($handleData, 'urlArr'))) {
                $dayData['publish_num'] = Db::raw('publish_num + 1');
                $dayData['publish_market'] = Db::raw('publish_market + 1');
            }
            if ($this->__isRecharge(Arr::get($handleData, 'urlArr'))) {
                $dayData['recharge'] = Db::raw('recharge + 1');
            }
            if ($this->__isRechargeSuccess(Arr::get($handleData, 'urlArr'))) {
                $dayData['recharge_success'] = Db::raw('recharge_success + 1');
            }
            //ip
            if ($this->__addIp($handleData)) {
                $dayData['ip_num'] = Db::raw('ip_num + 1');
            }

            if ($statId = $this->__checkStatExit($dayData)) {
                $dayData['id'] = $statId;
            }

            Data::save('behavior_stat', $dayData);

        }

    }


    /**
     * 是否增加 IP
     * @param $handleData
     *
     * @return bool
     */
    private function __addIp($handleData)
    {
        $count = Db::name('user_behavior_log')
            ->where('ip', Arr::get($handleData, 'ip'))
            ->where('id', '<=', Arr::get($handleData, 'logId'))
            ->where('created_at', '>=', $this->todayStart)
            ->where('created_at', '<=', $this->todayEnd)
            ->count();
        if ($count > 1) {
            return false;
        }

        return true;
    }


    /**
     * 是否是发布兼职
     * @param $urlArr
     *
     * @return bool
     */
    private function __isPublishJob($urlArr)
    {
        if (Arr::valueEq($urlArr, 1, 'jobs') &&
        Arr::valueEq($urlArr, 2, 'addjob')) {
            return true;
        }
        return false;
    }

    /**
     * 是否是发布二手商品
     * @param $urlArr
     *
     * @return bool
     */
    private function __isPublishMarket($urlArr)
    {
        if (Arr::valueEq($urlArr, 1, 'market') &&
            Arr::valueEq($urlArr, 2, 'publishgoods')) {
            return true;
        }
        return false;
    }

    /**
     * 是否是充值界面
     * @param $urlArr
     *
     * @return bool
     */
    private function __isRecharge($urlArr)
    {
        if (Arr::valueEq($urlArr, 1, 'userwallet') &&
            Arr::valueEq($urlArr, 2, 'buybean')) {
            return true;
        }
        return false;
    }

    /**
     * 是否是充值成功回调
     * @param $urlArr
     *
     * @return bool
     */
    private function __isRechargeSuccess($urlArr)
    {
        if (Arr::valueEq($urlArr, 1, 'user') &&
            Arr::valueEq($urlArr, 2, 'buybeannotify')) {
            return true;
        }
        return false;
    }


    /**
     * 检测统计是否存在
     * @param $data
     *
     * @return int
     */
    private function __checkStatExit($data)
    {
        return Db::name('behavior_stat')
            ->where('type', Arr::get($data, 'type'))
            ->where('start_time', Arr::get($data, 'start_time'))
            ->where('end_time', Arr::get($data, 'end_time'))
            ->value('id') ?: 0;
    }

    

    /**
     * 缺失是否需要处理
     * @param $handleData
     *
     * @return bool|mixed
     */
    protected function isHandle($handleData)
    {
        $this->isWeb = false;
        $this->isApi = false;

        //api 接口
        if (Arr::valueEq($handleData['urlArr'], 0, $this->apiSuffix)) {
            $this->isApi = true;
            return true;
        }

        //web界面 无具体url
        if (empty($handleData['urlArr'])) {
            $this->isWeb = true;
            return true;
        }


        //web界面
        if (Arr::valueEq($handleData['urlArr'], 0, $this->webSuffix)) {
            $this->isWeb = true;
            return true;
        }

        return true;
    }


    /**
     * 处理总表的月度 + 总量
     * @return mixed|void
     * @throws \think\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @throws \think\exception\PDOException
     */
    public function handleMonthAndTotal()
    {
        //处理月度
        $monthResult = Db::name('behavior_stat')
            ->where('type', 1)
            ->where('start_time', '>=', $this->monthStart)
            ->where('end_time', '<=', $this->monthEnd)
            ->field('SUM(click_num) as click_num')
            ->field('SUM(uv) as uv')
            ->field('SUM(api_num) as api_num')
            ->field('SUM(publish_num) as publish_num')
            ->field('SUM(publish_job) as publish_job')
            ->field('SUM(publish_market) as publish_market')
            ->field('SUM(recharge) as recharge')
            ->field('SUM(recharge_success) as recharge_success')
            ->field('SUM(ip_num) as ip_num')
            ->find() ?: [];

        $monthData = [
            'type'              => 2,
            'click_num'         => Arr::get($monthResult, 'click_num', 1),
            'uv'                => Arr::get($monthResult, 'uv', 1),
            'api_num'           => Arr::get($monthResult, 'api_num', 1),
            'publish_num'       => Arr::get($monthResult, 'publish_num', 1),
            'publish_job'       => Arr::get($monthResult, 'publish_job', 1),
            'publish_market'    => Arr::get($monthResult, 'publish_market', 1),
            'recharge'          => Arr::get($monthResult, 'recharge', 1),
            'recharge_success'  => Arr::get($monthResult, 'recharge_success', 1),
            'ip_num'            => Arr::get($monthResult, 'ip_num', 1),
            'start_time'        => $this->monthStart,
            'end_time'          => $this->monthEnd
        ];

        if ($monthStatId = $this->__checkStatExit($monthData)) {
            $monthData['id'] = $monthStatId;
        }
        Data::save('behavior_stat', $monthData);



        //处理总量
        $totalResult = Db::name('behavior_stat')
            ->where('type', 2)
            ->field('SUM(click_num) as click_num')
            ->field('SUM(uv) as uv')
            ->field('SUM(api_num) as api_num')
            ->field('SUM(publish_num) as publish_num')
            ->field('SUM(publish_job) as publish_job')
            ->field('SUM(publish_market) as publish_market')
            ->field('SUM(recharge) as recharge')
            ->field('SUM(recharge_success) as recharge_success')
            ->field('SUM(ip_num) as ip_num')
            ->find() ?: [];

        $totalData = [
            'type'              => 3,
            'click_num'         => Arr::get($totalResult, 'click_num', 1),
            'uv'                => Arr::get($totalResult, 'uv', 1),
            'api_num'           => Arr::get($totalResult, 'api_num', 1),
            'publish_num'       => Arr::get($totalResult, 'publish_num', 1),
            'publish_job'       => Arr::get($totalResult, 'publish_job', 1),
            'publish_market'    => Arr::get($totalResult, 'publish_market', 1),
            'recharge'          => Arr::get($totalResult, 'recharge', 1),
            'recharge_success'  => Arr::get($totalResult, 'recharge_success', 1),
            'ip_num'            => Arr::get($totalResult, 'ip_num', 1),
        ];

        if ($totalStatId = $this->__checkStatExit($totalData)) {
            $totalData['id'] = $totalStatId;
        }
        Data::save('behavior_stat', $totalData);


    }








}
